package data

import (
	"fmt"
	"github.com/elastic/go-elasticsearch/v8"
	"github.com/go-kratos/kratos/v2/log"
	"github.com/google/wire"
	"github.com/redis/go-redis/v9"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"review-service/dal/query"
	"review-service/internal/conf"
)

// ProviderSet is data providers.
var ProviderSet = wire.NewSet(NewDB, NewData, NewES, NewRedisClient, NewReviewRepo)

// Data .
type Data struct {
	// TODO wrapped database client
	Q   *query.Query
	es  *elasticsearch.TypedClient
	rdb *redis.Client
}

// NewData .
func NewData(db *gorm.DB, es *elasticsearch.TypedClient, rdb *redis.Client, logger log.Logger) (*Data, func(), error) {
	cleanup := func() {
		log.NewHelper(logger).Info("closing the data resources")
	}
	//非常重要 为gen生成的query代码指定数据库对象
	query.SetDefault(db)
	return &Data{
		Q:   query.Q,
		es:  es,
		rdb: rdb,
	}, cleanup, nil
}

func NewDB(conf *conf.Data) (*gorm.DB, error) {
	return gorm.Open(mysql.Open(conf.Database.Source))
}

func NewES(c *conf.ES) (*elasticsearch.TypedClient, error) {
	// ES 配置
	cfg := elasticsearch.Config{
		Addresses: c.Addresses,
	}
	// 创建客户端连接
	client, err := elasticsearch.NewTypedClient(cfg)
	if err != nil {
		fmt.Printf("elasticsearch.NewTypedClient failed, err:%v\n", err)
		return nil, err
	}
	return client, nil
}

func NewRedisClient(cfg *conf.Data) *redis.Client {
	return redis.NewClient(&redis.Options{
		Addr:         cfg.Redis.Addr,
		WriteTimeout: cfg.Redis.WriteTimeout.AsDuration(),
		ReadTimeout:  cfg.Redis.ReadTimeout.AsDuration(),
	})
}
